using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.U2D;
using UnityEngine;
using UnityEngine.U2D;

namespace HEFramework
{
    /// <summary>
    ///
    /// 图集生成工具
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2024-09-20 16:39:46
    /// ----------------------------------------
    /// </summary>
    public class AtlasBuildEditor : EditorWindow, IHasCustomMenu
    {
        private const int NAME_LENGTH = 120;
        private const int VALUE_LENGTH = 350;
        private const int NAME_HEIGHT = 18;
        private const int HELP_LENGTH = 475;


        private const string NAME_SUFFIX = "Atlas";
        private const string FILE_SUFFIX = ".spriteatlas";
        private GUILayoutOption[] nameOptions;
        private GUILayoutOption[] valueOptions;

        private string path;
        private string name;

        /// <summary>
        /// 打开编辑面板时初始化
        /// </summary>
        private void Awake()
        {
            nameOptions = new[] { GUILayout.Width(NAME_LENGTH), GUILayout.Height(NAME_HEIGHT) };
            valueOptions = new[] { GUILayout.Width(VALUE_LENGTH), GUILayout.Height(NAME_HEIGHT) };
        }

        /// <summary>
        /// 打开设置面板
        /// </summary>
        [MenuItem("MyTools/Atlas", false, 5)]
        public static void OpenSettingsWindow()
        {
            try
            {
                if (EditorApplication.isCompiling)
                {
                    return;
                }

                var window = GetWindowWithRect<AtlasBuildEditor>(new Rect(0, 0, 520, 300), true, "Atlas Build", true);
                window.Show();
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
            }
        }

        public void AddItemsToMenu(GenericMenu _menu)
        {
        }


        private void OnGUI()
        {
            AtlasGUIStyle.Ensure();

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("选择图集生成目录", GUILayout.Width(150), GUILayout.Height(20)))
            {
                string title = "Open Folder";
                // 以Assets文件夹为默认目录
                string directory = Application.dataPath;
                path = EditorUtility.OpenFolderPanel(title, directory, "").RB();
            }

            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("名字", AtlasGUIStyle.Label, nameOptions);
            if (!string.IsNullOrEmpty(path))
            {
                if (string.IsNullOrEmpty(name))
                {
                    name = path.RB().Split("/").Last() + NAME_SUFFIX;
                }
            }

            GUILayout.Label(name, AtlasGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            if (GUILayout.Button("生成"))
            {
                Build();
            }

            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("说明", AtlasGUIStyle.BoldLabel, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            string cnStr =
                "选择图元文件夹，点击生成，在该文件夹下生成一个图集。";
            GUILayout.Label(cnStr, AtlasGUIStyle.TextArea, GUILayout.Width(HELP_LENGTH), GUILayout.Height(20));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("注意事项", AtlasGUIStyle.BoldLabel, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            cnStr =
                "1.图集要确保勾选IncludeInBuild，打包的Scene无引用图集内图元时，不会造成包体大小增加的情况。不勾选需要自己处理延迟回调，不推荐。\n" +
                "2.使用图集后，无需Load图集，直接Load图元就行，合批会自动触发。\n" +
                "3.打AB包时，图集与包含的图元放在同文件夹下。不放一起，打包图元AB包时会自动把相应的图集也纳入到该图元AB包内，大小和放一起一样。\n" +
                "4.不推荐单独给图集打AB，容易造成资源冗余。\n" +
                "5.使用图集后，从AB包读取的图元从Texture2D变成Sprite类型，为了避免Bug，读取时传入的泛型类型使用UnityEngine.Object，资源返回时进行区分处理。";
            GUILayout.Label(cnStr, AtlasGUIStyle.TextArea, GUILayout.Width(HELP_LENGTH), GUILayout.Height(110));
            GUILayout.EndHorizontal();
        }


        private void Build()
        {
            if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(name))
            {
                return;
            }

            //创建SpriteAtlas
            SpriteAtlas spriteAtlas = new SpriteAtlas();

            //设置打包选项
            SpriteAtlasPackingSettings packSettings = new SpriteAtlasPackingSettings()
            {
                blockOffset = 1,
                padding = 4,
                enableRotation = false,
                enableTightPacking = false
            };
            spriteAtlas.SetPackingSettings(packSettings);

            //设置纹理选项
            TextureImporterPlatformSettings platformSettings = new TextureImporterPlatformSettings()
            {
                maxTextureSize = 2048,
                format = TextureImporterFormat.Automatic,
            };
            spriteAtlas.SetPlatformSettings(platformSettings);

            string projectPath = Application.dataPath;
            string filePath = "Assets" + path.Substring(projectPath.Length).RB();

            //添加目录本身作为Object for Packing
            UnityEngine.Object folderObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(filePath);
            if (folderObject != null)
            {
                spriteAtlas.Add(new[] { folderObject });
            }

            //保存SpriteAtlas到项目中
            string atlasPath = filePath + "/" + name + FILE_SUFFIX;
            AssetDatabase.CreateAsset(spriteAtlas, atlasPath);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            Debug.Log($"Atlas build succeed : {atlasPath}");
        }
    }
}